local gamelib = require "club.threecard.gamelib"
local slotlib = require "club.threecard.slotlib"
local components = slotlib.require "components"

local slot_system = slotlib.systems.slot_system
local class = gamelib.entitas.class
local Matcher = gamelib.entitas.Matcher
local GroupEvent = gamelib.entitas.GroupEvent


local scatter_system = class("scatter_system", slot_system)

function scatter_system:get_trigger()
    return {{Matcher({components.frames_component}), GroupEvent.ADDED | GroupEvent.UPDATE}};
end

function scatter_system:filter(entity)
    return entity:has(components.frames_component)
end

local function filter_frame(frames)
    local ret = {}    

    for _, frame in ipairs(frames) do
        if frame.type == slotlib.frame_type.scatter_hit then
            table.insert(ret, frame);
        end
    end

    return ret;
end

function scatter_system:execute(entitas)
    if entitas:size() ~= 1 then
        gamelib.log.error("数据错误，结果组件不可能>1")
        return;
    end

    entitas:foreach(function(e)
        local frames = e:get(components.frames_component).frames;
        frames = filter_frame(frames);
        if #frames == 0 then
            return;
        end

        local active_indexes = {};
        for _, frame in ipairs(frames) do
            for _, key in ipairs(frame.keys) do
                local y = key % 0x10000 + 1;
                local x = math.floor(key / 0x10000);
                table.insert(active_indexes, {x = x, y = y});
            end
        end

        local active_symbols = self.ingame.machine:get_elements_xy(active_indexes);

        local original_parent = nil;
        if e:has(components.cover_symbol_component) then
            local cover_symbol_component = e:get(components.cover_symbol_component)
            for _, symbol in ipairs(active_symbols) do
                if original_parent == nil then
                    original_parent = symbol.transform.parent;
                end
                symbol:set_parent(cover_symbol_component.cover_parent);
            end    
        end

        self.original_parent = original_parent;
        self.active_symbols = active_symbols;

        for _, symbol in ipairs(active_symbols) do
            symbol:active(true);
        end
        self:wait(0.1);

        for _, symbol in ipairs(active_symbols) do
            symbol:perform(true);
            self:wait(0.1);
        end
        self:wait(1);

        if original_parent then
            for _, symbol in ipairs(active_symbols) do
                symbol:set_parent(original_parent);
            end
        end
    end)
end

function scatter_system:_finish()
    scatter_system.super._finish(self);
    if self.active_symbols then
        for _, symbol in ipairs(self.active_symbols) do
            symbol:active(false);
        end 
    end
end

return scatter_system